package NW_MC;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import NWPackage.Cell;
import NWPackage.ProbabilitiesMatrix;
import NWPackage.ProbabilityCell;

public class FullMonteCarlo extends MonteCarlo {

	private MCEntropyMatrix winnersStatistics;
	private ProbabilitiesMatrix normalizeProbabilityMatrix;
	private List<String> optionalWinners;
	private Random rand3;
	
	public FullMonteCarlo(){
		rand3 = new Random();
	}
	
	protected double CalcAssumptionEntropy(ProbabilitiesMatrix normalizeProbabilityMatrix,Cell assumption, List<String> optionalWinners) throws Exception {
		
		winnersStatistics = new MCEntropyMatrix(optionalWinners);
		this.normalizeProbabilityMatrix = normalizeProbabilityMatrix;
		this.optionalWinners = optionalWinners;
		
		CalcFullWinnerStatistics();
		
		//after all iterations - calc the entropy of each Candidate:
		return winnersStatistics.calcFullWeightedEntropy(normalizeProbabilityMatrix.getAgentTotalProbability(assumption.getAgentName()));
	}
	
	
	private void CalcFullWinnerStatistics() throws Exception
	{
		List<ProbabilityCell> cellsArray = new ArrayList<ProbabilityCell>();
		String[] agets = normalizeProbabilityMatrix.getAgentsNames();
		CalcFullRec(cellsArray,0,agets);
		
	}


	private void CalcFullRec(List<ProbabilityCell> cellsArray, int agentIndex, String[] agets) throws Exception {
		
		List<ProbabilityCell> myList = normalizeProbabilityMatrix.getAgentProbs(agets[agentIndex]);
		
		//when last agent:
		if (agentIndex==agets.length-1)
		{
			for (ProbabilityCell probabilityCell : myList) {
				cellsArray.add(probabilityCell);
				UpdateStatistics(cellsArray);
				cellsArray.remove(probabilityCell);
			}
		}
		else
		{
			for (ProbabilityCell probabilityCell : myList) {
				cellsArray.add(probabilityCell);
				CalcFullRec(cellsArray,agentIndex+1,agets);
				cellsArray.remove(probabilityCell);
			}
		}
		
	}


	private void UpdateStatistics(List<ProbabilityCell> cellsArray) throws Exception {
		RandomMatrix rMatrix = new RandomMatrix(optionalWinners);
		double winningProb = 1.0;
		for (ProbabilityCell probability : cellsArray) {
			rMatrix.setCell(probability);
			winningProb*=probability.getProbability();
		}
		try {
			List<String> winnerList =  rMatrix.getWinnerCandidate();			
			int idx = rand3.nextInt(winnerList.size());
			String winner = winnerList.get(idx);			
			winnersStatistics.increaseCandidateWinner(winner,winningProb);
		} 
		catch (Exception e) {
			System.out.println("cannot increase the Candidate");
			e.printStackTrace();
		}

	}
}
